<template>
  <div class="landing-page-builder">
    <!-- 列表/编辑切换 -->
    <div v-if="!isEditing" class="landing-page-list">
      <!-- 搜索区域 -->
      <el-card class="mb-4">
        <el-form
          :model="queryParams"
          ref="queryFormRef"
          :inline="true"
          label-width="68px"
        >
          <el-form-item label="标题" prop="title">
            <el-input
              v-model="queryParams.title"
              placeholder="请输入落地页标题"
              clearable
              @keyup.enter="handleQuery"
            />
          </el-form-item>
          <el-form-item label="状态" prop="status">
            <el-select
              v-model="queryParams.status"
              placeholder="请选择状态"
              clearable
              class="!w-[180px]"
            >
              <el-option
                v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
                :key="dict.value"
                :label="dict.label"
                :value="dict.value"
              />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="handleQuery">
              <Icon icon="ep:search" class="mr-5px" /> 搜索
            </el-button>
            <el-button @click="resetQuery">
              <Icon icon="ep:refresh" class="mr-5px" /> 重置
            </el-button>
          </el-form-item>
        </el-form>
      </el-card>

      <!-- 操作工具栏 -->
      <el-card class="mb-4">
        <div class="flex justify-between items-center">
          <div class="flex gap-2">
            <el-button type="primary" @click="handleCreate">
              <Icon icon="ep:plus" class="mr-5px" /> 新增落地页
            </el-button>
          </div>
          <el-tag type="info" class="!border-none">
            共 {{ total }} 个落地页
          </el-tag>
        </div>
      </el-card>

      <!-- 列表卡片 -->
      <el-card>
        <el-table
          :data="landingPageList"
          v-loading="loading"
          :stripe="true"
          :border="true"
          class="w-full"
        >
          <!-- 标题列 -->
          <el-table-column prop="title" label="标题" min-width="200">
            <template #default="{ row }">
              <div class="flex items-center">
                <Icon icon="ep:document" class="mr-2 text-gray-400" />
                <span class="font-medium">{{ row.title }}</span>
              </div>
            </template>
          </el-table-column>
          
          <!-- 设备类型列 -->
          <el-table-column prop="device" label="设备类型" width="120" align="center">
            <template #default="{ row }">
              <el-tag :type="row.device === 'mobile' ? 'warning' : 'primary'" size="small">
                <Icon :icon="row.device === 'mobile' ? 'ep:mobile' : 'ep:monitor'" class="mr-1" />
                {{ row.device === 'mobile' ? '移动端' : 'PC端' }}
              </el-tag>
            </template>
          </el-table-column>
          
          <!-- 状态列 -->
          <el-table-column prop="status" label="状态" width="100" align="center">
            <template #default="{ row }">
              <el-tag
                :type="row.status === 0 ? 'success' : 'danger'"
                size="small"
              >
                {{ row.status === 0 ? '已启用' : '已停用' }}
              </el-tag>
            </template>
          </el-table-column>
          
          <!-- 创建时间列 -->
          <el-table-column prop="createTime" label="创建时间" width="180" align="center">
            <template #default="{ row }">
              <span class="text-gray-500">{{ formatDate(row.createTime) }}</span>
            </template>
          </el-table-column>
          
          <!-- 操作列 -->
          <el-table-column label="操作" width="250" fixed="right" align="center">
            <template #default="{ row }">
              <el-button-group>
                <el-button
                  type="primary"
                  link
                  @click="handleEdit(row)"
                  title="编辑"
                >
                  <Icon icon="ep:edit" />
                </el-button>
                <el-button
                  type="primary"
                  link
                  @click="handlePreview(row)"
                  title="预览"
                >
                  <Icon icon="ep:view" />
                </el-button>
                <el-button
                  :type="row.status === 0 ? 'danger' : 'success'"
                  link
                  @click="handleUpdateStatus(row.id, row.status === 0 ? 1 : 0)"
                  :title="row.status === 0 ? '停用' : '启用'"
                >
                  <Icon :icon="row.status === 0 ? 'ep:close' : 'ep:check'" />
                </el-button>
                <el-button
                  type="danger"
                  link
                  @click="handleDelete(row.id)"
                  :disabled="row.status === 0"
                  title="删除"
                >
                  <Icon icon="ep:delete" />
                </el-button>
              </el-button-group>
            </template>
          </el-table-column>
        </el-table>

        <!-- 分页器 -->
        <div class="mt-4">
          <pagination
            v-model:total="total"
            v-model:page="queryParams.pageNo"
            v-model:limit="queryParams.pageSize"
            @pagination="loadLandingPageList"
          />
        </div>
      </el-card>
    </div>

    <!-- 编辑器界面 -->
    <div v-else class="landing-page-editor">
      <!-- 顶部操作栏 -->
      <div class="builder-header">
        <div class="flex items-center justify-between">
          <div class="flex gap-2">
            <el-button @click="handleBack">
              <Icon icon="ep:back" class="mr-5px" /> 返回
            </el-button>
            <el-button type="primary" @click="handlePreview">
              <Icon icon="ep:view" class="mr-5px" /> 预览
            </el-button>
            <el-button type="success" @click="handleSave">
              <Icon icon="ep:upload" class="mr-5px" /> 保存
            </el-button>
          </div>
          <div></div>
        </div>
      </div>

      <div class="builder-container">
        <!-- 左侧组件列表 -->
        <div class="component-list">
          <el-card class="h-full">
            <template #header>
              <div class="flex items-center">
                <span class="text-lg font-medium">组件列表</span>
              </div>
            </template>
            
            <el-collapse v-model="activeCollapse">
              <el-collapse-item title="基础组件" name="basic">
                <draggable 
                  :list="basicComponents"
                  :group="{ name: 'components', pull: 'clone', put: false }"
                  :sort="false"
                  item-key="type"
                  :clone="cloneComponent"
                  class="component-group"
                >
                  <template #item="{ element }">
                    <div class="component-item">
                      <Icon :icon="element.icon" class="mr-2" />
                      {{ element.label }}
                    </div>
                  </template>
                </draggable>
              </el-collapse-item>

              <el-collapse-item title="表单组件" name="form">
                <draggable 
                  :list="formComponents"
                  :group="{ name: 'components', pull: 'clone', put: false }"
                  :sort="false"
                  item-key="type"
                  :clone="cloneComponent"
                  class="component-group"
                >
                  <template #item="{ element }">
                    <div class="component-item">
                      <Icon :icon="element.icon" class="mr-2" />
                      {{ element.label }}
                    </div>
                  </template>
                </draggable>
              </el-collapse-item>
            </el-collapse>
          </el-card>
        </div>

        <!-- 中间画布区域 -->
        <div class="canvas-container">
          <el-card class="h-full">
            <template #header>
              <div class="flex items-center justify-between">
                <span class="text-lg font-medium">画布</span>
                <el-button-group>
                  <el-button 
                    :type="device === 'desktop' ? 'primary' : ''" 
                    @click="device = 'desktop'"
                    title="PC端预览"
                  >
                    <Icon icon="material-symbols:desktop-windows-outline" />
                  </el-button>
                  <el-button 
                    :type="device === 'mobile' ? 'primary' : ''" 
                    @click="device = 'mobile'"
                    title="移动端预览"
                  >
                    <Icon icon="material-symbols:smartphone-outline" />
                  </el-button>
                </el-button-group>
              </div>
            </template>

            <div class="canvas-wrapper">
              <div class="canvas-scroll-container">
                <div :class="['canvas', device]">
                  <draggable
                    v-model="canvasComponents"
                    group="components"
                    item-key="id"
                    class="canvas-content"
                    :class="{ 'is-dragging': isDragging }"
                    @start="dragStart"
                    @end="dragEnd"
                  >
                    <template #item="{ element }">
                      <div 
                        :class="['canvas-item', { active: currentComponent?.id === element.id }]"
                        @click="selectComponent(element)"
                      >
                        <component :is="componentMap[element.type]" v-bind="element.props" />
                        <div class="component-actions">
                          <el-button-group>
                            <el-button 
                              type="primary" 
                              link
                              @click.stop="moveUp(element)"
                              :disabled="canvasComponents.indexOf(element) === 0"
                            >
                              <Icon icon="ep:arrow-up" />
                            </el-button>
                            <el-button 
                              type="primary" 
                              link
                              @click.stop="moveDown(element)"
                              :disabled="canvasComponents.indexOf(element) === canvasComponents.length - 1"
                            >
                              <Icon icon="ep:arrow-down" />
                            </el-button>
                            <el-button 
                              type="danger" 
                              link
                              @click.stop="removeComponent(element)"
                            >
                              <Icon icon="ep:delete" />
                            </el-button>
                          </el-button-group>
                        </div>
                      </div>
                    </template>
                  </draggable>
                </div>
              </div>
            </div>
          </el-card>
        </div>

        <!-- 右侧配置面板 -->
        <div class="config-panel">
          <el-card class="h-full">
            <template #header>
              <div class="flex items-center">
                <span class="text-lg font-medium">组件配置</span>
              </div>
            </template>
            
            <div v-if="currentComponent" class="config-content">
              <component 
                :is="configMap[currentComponent.type]"
                v-model="currentComponent.props"
              />
            </div>
            <el-empty v-else description="请选择组件进行配置" />
          </el-card>
        </div>
      </div>

      <!-- 修改预览弹窗 -->
      <el-dialog
        v-model="previewVisible"
        :title="`预览 - ${device === 'mobile' ? '移动端' : 'PC端'}`"
        :fullscreen="true"
        :show-close="true"
        :close-on-click-modal="false"
        :close-on-press-escape="false"
        destroy-on-close
        class="preview-dialog"
      >
        <template #header>
          <div class="preview-header">
            <span class="text-lg font-medium">预览</span>
            <el-button-group>
              <el-button
                :type="device === 'desktop' ? 'primary' : ''"
                @click="device = 'desktop'"
              >
                <Icon icon="material-symbols:desktop-windows-outline" class="mr-1" />PC端
              </el-button>
              <el-button
                :type="device === 'mobile' ? 'primary' : ''"
                @click="device = 'mobile'"
              >
                <Icon icon="material-symbols:smartphone-outline" class="mr-1" />移动端
              </el-button>
            </el-button-group>
          </div>
        </template>

        <div class="preview-container">
          <div :class="['preview-content', device]">
            <template v-if="previewComponents.length > 0">
              <div v-for="(item, index) in previewComponents" :key="index" class="preview-item">
                <component
                  :is="componentMap[item.type]"
                  v-bind="item.props || {}"
                />
              </div>
            </template>
            <el-empty v-else description="暂无内容" />
          </div>
        </div>
      </el-dialog>

      <!-- 添加保存弹窗 -->
      <el-dialog
        v-model="saveDialogVisible"
        title="保存落地页"
        width="500px"
      >
        <el-form :model="saveForm" label-width="80px">
          <el-form-item label="标题" required>
            <el-input 
              v-model="saveForm.title" 
              placeholder="请输入落地页标题"
              maxlength="50"
              show-word-limit
            />
          </el-form-item>
        </el-form>
        <template #footer>
          <el-button @click="saveDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitSave" :loading="saveLoading">
            确认
          </el-button>
        </template>
      </el-dialog>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted, nextTick, watch } from 'vue'
import { useI18n } from '@/hooks/web/useI18n'
import draggable from 'vuedraggable'
import { v4 as uuidv4 } from 'uuid'
import { useMessage } from '@/hooks/web/useMessage'
import type { CanvasComponent, ComponentType } from './types'
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { formatDate } from '@/utils/formatTime'
import { ElDialog } from 'element-plus'
// 导入组件
import LpInput from './components/LpInput.vue'
import LpSelect from './components/LpSelect.vue'
import LpCheckbox from './components/LpCheckbox.vue'
import LpImage from './components/LpImage.vue'
import LpButton from './components/LpButton.vue'
// 导入配置面板
import InputConfig from './configs/InputConfig.vue'
import SelectConfig from './configs/SelectConfig.vue'
import CheckboxConfig from './configs/CheckboxConfig.vue'
import ImageConfig from './configs/ImageConfig.vue'
import ButtonConfig from './configs/ButtonConfig.vue'
import { 
  getLandingPage, 
  createLandingPage, 
  updateLandingPage,
  getLandingPagePage,
  deleteLandingPage,
  updateLandingPageStatus,
  type LandingPageVO
} from '@/api/weiyi/landingpage'

const message = useMessage()
const { t } = useI18n()

// 组件映射表
const componentMap = {
  'lp-input': LpInput,
  'lp-select': LpSelect,
  'lp-checkbox': LpCheckbox,
  'lp-image': LpImage,
  'lp-button': LpButton
}

// 配置面板映射表
const configMap = {
  'lp-input': InputConfig,
  'lp-select': SelectConfig,
  'lp-checkbox': CheckboxConfig,
  'lp-image': ImageConfig,
  'lp-button': ButtonConfig
}

// 基础组件列表
const basicComponents = ref([
  { type: 'lp-image', label: '图片', icon: 'ep:picture' },
  { type: 'lp-button', label: '按钮', icon: 'ep:pointer' }
])

// 表单组件列表
const formComponents = ref([
  { type: 'lp-input', label: '输入框', icon: 'ep:edit' },
  { type: 'lp-select', label: '下拉选择', icon: 'ep:select' },
  { type: 'lp-checkbox', label: '多选框', icon: 'ep:check' }
])

const activeCollapse = ref(['basic', 'form'])
const device = ref<'desktop' | 'mobile'>('desktop')
const canvasComponents = ref<CanvasComponent[]>([])
const currentComponent = ref<CanvasComponent | null>(null)
const previewVisible = ref(false)
const previewComponents = ref<any[]>([])
const isDragging = ref(false)
const currentId = ref<number | null>(null)
const isEditing = ref(false)
const loading = ref(false)
const landingPageList = ref<LandingPageVO[]>([])
const total = ref(0)
const title = ref('')

const queryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  title: undefined,
  status: undefined,
  createTime: []
})

const queryFormRef = ref()

const saveDialogVisible = ref(false)
const saveLoading = ref(false)
const saveForm = reactive({
  title: ''
})

// 拖拽相关
const dragStart = () => {
  currentComponent.value = null
  isDragging.value = true
}

const dragEnd = () => {
  isDragging.value = false
}

// 获取组件默认属性
const getDefaultProps = (type: string) => {
  const defaultProps = {
    'lp-input': { placeholder: '请输入', required: false },
    'lp-select': { options: [], placeholder: '请选择' },
    'lp-checkbox': { options: [], label: '多选框' },
    'lp-image': { src: '', alt: '' },
    'lp-button': {
      text: '按钮',
      type: 'primary',
      backgroundColor: '',
      textColor: '',
      borderColor: '',
      shape: 'default',
      size: 'default',
      block: false
    }
  }
  return defaultProps[type] || {}
}

// 选择组件
const selectComponent = (component) => {
  currentComponent.value = component
}

// 移动组件
const moveUp = (component) => {
  const index = canvasComponents.value.indexOf(component)
  if (index > 0) {
    canvasComponents.value.splice(index, 1)
    canvasComponents.value.splice(index - 1, 0, component)
  }
}

const moveDown = (component) => {
  const index = canvasComponents.value.indexOf(component)
  if (index < canvasComponents.value.length - 1) {
    canvasComponents.value.splice(index, 1)
    canvasComponents.value.splice(index + 1, 0, component)
  }
}

// 删除组件
const removeComponent = (component) => {
  const index = canvasComponents.value.indexOf(component)
  canvasComponents.value.splice(index, 1)
  if (currentComponent.value === component) {
    currentComponent.value = null
  }
}

// 修改编辑方法
const handleEdit = async (row) => {
  if (!row?.id) {
    message.error('无效的编辑参数')
    return
  }

  try {
    // 先加载数据
    const data = await getLandingPage(row.id)
    if (!data) {
      throw new Error('获取落地页数据失败')
    }

    // 设置基础数据
    currentId.value = data.id
    title.value = data.title
    
    // 解析组件数据
    if (data.content) {
      canvasComponents.value = JSON.parse(data.content)
    } else {
      canvasComponents.value = []
    }

    // 切换到编辑状态
    isEditing.value = true
  } catch (error) {
    console.error('编辑失败:', error)
    message.error('加载落地页失败')
  }
}

// 修改预览方法
const handlePreview = async (row?: any) => {
  try {
    // 重置预览数据
    previewComponents.value = []
    previewVisible.value = false

    // 从列表预览
    if (row?.id) {
      const data = await getLandingPage(row.id)
      if (!data?.content) {
        throw new Error('落地页内容为空')
      }
      previewComponents.value = JSON.parse(data.content)
      previewVisible.value = true
      return
    }

    // 从编辑器预览
    if (isEditing.value) {
      if (!canvasComponents.value?.length) {
        message.warning('画布内容为空')
        return
      }
      previewComponents.value = [...canvasComponents.value]
      previewVisible.value = true
      return
    }

    throw new Error('无效的预览参数')
  } catch (error) {
    console.error('预览失败:', error)
    message.error('预览失败：' + (error.message || '未知错误'))
  }
}

// 预览弹窗关闭时的处理
const handlePreviewClose = () => {
  previewVisible.value = false
  previewComponents.value = []
}

// 保存
const handleSave = () => {
  // 检查组件数据
  if (!canvasComponents.value || canvasComponents.value.length === 0) {
    message.warning('请先添加组件')
    return
  }
  
  // 打开保存弹窗,如果是编辑模式则填入原标题
  saveForm.title = title.value || ''
  saveDialogVisible.value = true
}

// 提交保存
const submitSave = async () => {
  try {
    // 校验标题
    if (!saveForm.title?.trim()) {
      message.warning('请输入落地页标题')
      return
    }

    saveLoading.value = true
    const data = {
      title: saveForm.title.trim(),
      content: JSON.stringify(canvasComponents.value),
      device: 'desktop', // 固定为 PC 端
      components: JSON.stringify(canvasComponents.value),
      status: 0
    }
    
    if (currentId.value) {
      await updateLandingPage({
        ...data,
        id: currentId.value
      })
    } else {
      await createLandingPage(data)
    }
    
    message.success('保存成功')
    saveDialogVisible.value = false
    await loadLandingPageList()
    handleBack()
  } catch (error) {
    console.error('保存失败:', error)
    message.error('保存失败：' + (error.message || '未知错误'))
  } finally {
    saveLoading.value = false
  }
}

// 克隆组件
const cloneComponent = (component: any) => {
  return {
    id: uuidv4(),
    type: component.type,
    props: getDefaultProps(component.type)
  }
}

// 加载落地页列表
const loadLandingPageList = async () => {
  loading.value = true
  try {
    const res = await getLandingPagePage(queryParams)
    landingPageList.value = res.list
    total.value = res.total
  } catch (error) {
    message.error('获取落地页列表失败')
  } finally {
    loading.value = false
  }
}

// 创建新落地页
const handleCreate = () => {
  currentId.value = null
  device.value = 'desktop'
  canvasComponents.value = []
  title.value = '' // 重置标题
  isEditing.value = true
}

// 返回列表
const handleBack = () => {
  isEditing.value = false
  loadLandingPageList()
}

// 删除落地页
const handleDelete = async (id: number) => {
  try {
    await message.confirm('确认要删除该落地页吗？')
    await deleteLandingPage(id)
    message.success('删除成功')
    loadLandingPageList()
  } catch (error) {
    message.error('删除失败')
  }
}

// 更新状态
const handleUpdateStatus = async (id: number, status: number) => {
  try {
    await message.confirm(`确认要${status === 0 ? '启用' : '停用'}该落地页吗？`)
    await updateLandingPageStatus(id, status)
    message.success(status === 0 ? '启用成功' : '停用成功')
    loadLandingPageList()
  } catch (error) {
    if (error?.code === 401) {
      message.error('请先登录')
    } else if (error?.message) {
      message.error('操作失败：' + error.message)
    }
  }
}

/** 搜索按钮操作 */
const handleQuery = () => {
  queryParams.pageNo = 1
  loadLandingPageList()
}

/** 重置按钮操作 */
const resetQuery = () => {
  queryFormRef.value?.resetFields()
  handleQuery()
}

// 监听组件数据变化
watch(canvasComponents, (newVal) => {
  console.log('组件数据变化:', newVal)
}, { deep: true })

// 监听设备类型变化
watch(device, () => {
  nextTick(() => {
    // 强制重新渲染
    if (canvasComponents.value.length > 0) {
      const temp = [...canvasComponents.value]
      canvasComponents.value = []
      nextTick(() => {
        canvasComponents.value = temp
      })
    }
  })
})

onMounted(() => {
  loadLandingPageList()
})
</script>

<style scoped>
.landing-page-builder {
  display: flex;
  height: 100vh;
  min-height: 0;
  padding: 16px;
  overflow: hidden;
  background: #f5f7fa;
  flex-direction: column;
  gap: 16px;
}

.builder-header {
  padding: 16px;
  background: #fff;
  border-radius: 4px;
  box-shadow: 0 1px 4px rgb(0 0 0 / 10%);
}

.builder-container {
  flex: 1;
  display: grid;
  grid-template-columns: 280px 1fr 320px;
  gap: 16px;
  min-height: 0;
  overflow: hidden;
}

.component-list,
.canvas-container,
.config-panel {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
}

.component-list .el-card__body {
  padding: 0;
  overflow: auto;
  flex: 1;
}

.component-list .el-collapse {
  border: none;
}

.canvas-container {
  display: flex;
  height: 100%;
  flex-direction: column;
}

.canvas-container .el-card {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.canvas-container .el-card__body {
  display: flex;
  padding: 0;
  flex-direction: column;
  flex: 1;
}

.canvas-wrapper {
  position: relative;
  display: flex;
  height: 100%;
  min-height: 0;
  padding: 0;
  flex-direction: column;
  flex: 1;
  background: #f5f7fa;
}

.canvas-scroll-container {
  display: flex;
  height: 100%;
  padding: 16px;
  overflow: auto;
  border-radius: 4px;
  flex-direction: column;
}

.canvas {
  position: relative;
  display: flex;
  width: 100%;
  height: 100%;
  background: #fff;
  border: 2px dashed #e4e7ed;
  transition: all 0.3s;
  flex-direction: column;
}

.canvas.desktop {
  width: 100%;
  height: calc(100vh - 200px);
  padding: 24px;
}

.canvas.mobile {
  height: 667px;
  max-width: 375px;
  padding: 16px;
  margin: 0 auto;
  box-shadow: 0 0 20px rgb(0 0 0 / 10%);
}

.canvas-content {
  display: flex;
  width: 100%;
  height: 100%;
  padding: 16px;
  overflow-y: auto;
  background: #fff;
  flex-direction: column;
  gap: 8px;
}

.canvas-content:empty {
  display: flex;
  width: 100%;
  height: 100%;
  background: rgb(247 248 250);
  border: 2px dashed #e4e7ed;
  border-radius: 4px;
  align-items: center;
  justify-content: center;
}

.canvas-content:empty::after {
  width: 100%;
  padding: 32px 0;
  font-size: 14px;
  font-weight: 500;
  color: #909399;
  text-align: center;
  content: '拖拽组件到这里';
}

.canvas-content.is-dragging {
  background: rgb(247 248 250);
  border: 2px dashed var(--el-color-primary);
}

.canvas-item {
  position: relative;
  z-index: 1;
  width: 100%;
  padding: 16px;
  margin-bottom: 8px;
  cursor: pointer;
  background: #fff;
  border: 1px solid transparent;
  border-radius: 4px;
  box-shadow: 0 1px 3px rgb(0 0 0 / 5%);
  transition: all 0.3s;
  user-select: none;
  
  &:hover {
    border-color: var(--el-color-primary);
    box-shadow: 0 2px 12px rgb(0 0 0 / 8%);
  }
}

.canvas-item.active {
  border-color: var(--el-color-primary);
  box-shadow: 0 0 0 2px var(--el-color-primary-light-8);
}

.component-actions {
  position: absolute;
  top: 50%;
  right: 8px;
  display: none;
  padding: 4px;
  background: #fff;
  border-radius: 4px;
  transform: translateY(-50%);
  box-shadow: 0 2px 12px rgb(0 0 0 / 10%);
}

.canvas-item:hover .component-actions {
  display: block;
}

.preview-dialog {
  .el-dialog {
    margin: 0 !important;
  }

  .el-dialog__header {
    padding: 0;
    margin: 0;
  }

  .el-dialog__body {
    height: calc(100vh - 60px);
    padding: 0;
    overflow: auto;
  }
}

.preview-header {
  display: flex;
  padding: 16px 24px;
  border-bottom: 1px solid #eee;
  align-items: center;
  justify-content: space-between;
}

.preview-container {
  height: 100%;
  padding: 24px;
  overflow: auto;
  background: #f5f7fa;
}

.preview-content {
  width: 100%;
  min-height: 100%;
  padding: 24px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgb(0 0 0 / 10%);
}

.preview-content.mobile {
  max-width: 375px;
  margin: 0 auto;
}

.preview-item {
  margin-bottom: 16px;
}

.config-content {
  padding: 16px;
}

.component-group {
  display: grid;
  min-height: 0;
  padding: 8px;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}

.component-item {
  display: flex;
  padding: 12px;
  white-space: nowrap;
  cursor: move;
  background: #fff;
  border: 1px dashed #dcdfe6;
  border-radius: 4px;
  transition: all 0.2s;
  user-select: none;
  align-items: center;
}

.component-item:hover {
  color: var(--el-color-primary);
  border-color: var(--el-color-primary);
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgb(0 0 0 / 8%);
}

/* 美化滚动条样式 */
.canvas-scroll-container::-webkit-scrollbar {
  width: 6px;
}

.canvas-scroll-container::-webkit-scrollbar-thumb {
  background-color: #909399;
  border-radius: 3px;
}

.canvas-scroll-container::-webkit-scrollbar-track {
  background-color: #f4f4f5;
}

/* 美化组件列表滚动条 */
.component-list .el-card__body::-webkit-scrollbar {
  width: 6px;
}

.component-list .el-card__body::-webkit-scrollbar-thumb {
  background-color: #909399;
  border-radius: 3px;
}

.component-list .el-card__body::-webkit-scrollbar-track {
  background-color: #f4f4f5;
}

/* 移除折叠面板边框 */
.component-list .el-collapse-item__wrap,
.component-list .el-collapse-item__content {
  padding: 0;
  border: none;
}

/* 美化画布内容的滚动条 */
.canvas-content::-webkit-scrollbar {
  width: 6px;
}

.canvas-content::-webkit-scrollbar-thumb {
  background-color: #909399;
  border-radius: 3px;
}

.canvas-content::-webkit-scrollbar-track {
  background-color: #f4f4f5;
}

.landing-page-list {
  min-height: 100vh;
  padding: 20px;
  background-color: #f5f7fa;
}

.el-card {
  border-radius: 8px;
  box-shadow: 0 1px 3px rgb(0 0 0 / 10%);
}

:deep(.el-table) {
  overflow: hidden;
  border-radius: 4px;
}

:deep(.el-table th) {
  font-weight: 600;
  background-color: #f5f7fa;
}

:deep(.el-button-group .el-button) {
  padding: 4px 8px;
}

:deep(.el-tag) {
  border-radius: 4px;
}

.el-button-group {
  display: inline-flex;
  gap: 4px;
}
</style> 